package com.knife.bbs.business;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import com.knife.bbs.object.BBSDir;
import com.knife.bbs.object.BBSDoc;
import com.knife.bbs.domain.BBSScore;
import com.knife.bbs.domain.Score;
import com.knife.bbs.object.UserInfo;
import com.knife.news.business.HTMLGenerater;
import com.knife.web.Globals;
import com.knife.web.tools.DbPageList;
import com.knife.web.tools.IPageList;

/**
 * BBS核心服务类
 */
public class BBSCoreService extends DAOSupportService {
	private static final int uploadImgScore = 0;// 上传图片积分
	private static final long randomCodeIntereval = 1000 * 60 * 60 * 24 * 7;// 7天

	private BBSDocService docService = new BBSDocService();
	private BBSDirService dirService = new BBSDirService();
	private static BBSCoreService singleton = new BBSCoreService();

	public static BBSCoreService getInstance() {
		return singleton;
	}

	public boolean canUploadImg(UserInfo user) {
		boolean ret = false;
		if (user != null) {
			if ((user.getScore() != null && user.getScore() > uploadImgScore))
				ret = true;
		}
		return ret;
	}

	public boolean noRandomCode(UserInfo user) {
		boolean ret = false;
		if (user != null) {
			if (user.getInputtime() != null) {
				if ((new Date().getTime() - user.getInputtime().getTime()) > randomCodeIntereval)
					ret = true;
			}
		}
		return ret;
	}

	public List getHotTopic(int num) {

		return changeListType(this.dao
				.query(com.knife.bbs.domain.BBSDoc.class,
						"status>=0  and  (parentId is null or (parentId='')) order by readTimes desc",
						null, 0, num));
	}

	public List getNewTopic(int num) {
		return changeListType(this.dao
				.query(com.knife.bbs.domain.BBSDoc.class,
						"status>=0  and  (parentId is null or (parentId='')) order by inputTime desc",
						null, 0, num));
	}

	public List getLastReplyTopic(int num) {
		return changeListType(this.dao
				.query(com.knife.bbs.domain.BBSDoc.class,
						"status>=0  and  (parentId is null or (parentId='')) and inputTime<>modifyTime order by modifyTime desc",
						null, 0, num));
	}

	public Number getTotalMember() {
		Number num = (Number) this.dao
				.uniqueResult("select count(*) from BBSUser where status>=0");
		return num;
	}

	public Number getTotalTopicNum() {
		Number num = (Number) this.dao
				.uniqueResult("select count(*) from BBSDoc where status>=0  and  (parentId is null or (parentId=''))");
		return num;
	}

	public Number getTotalMessageNum() {
		Number num = (Number) this.dao
				.uniqueResult("select count(*) from BBSDoc where status>=0 ");
		return num;
	}

	public Number getTodayMessageNum() {
		java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat(
				"yyyy-MM-dd");
		Number num = (Number) this.dao
				.uniqueResult("select count(*) from BBSDoc where status>=0 and inputTime>='"
						+ dateFormat.format(new Date()) + "'");
		return num;
	}

	public List getTodayMessages() {
		java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat(
				"yyyy-MM-dd");
		List ms = changeListType(this.dao.query(com.knife.bbs.domain.BBSDoc.class, "status>=0 and inputTime>='"
				+ dateFormat.format(new Date()) + "'"));
		return ms;
	}

	public Number getYesterdayMessageNum() {

		Calendar ca = Calendar.getInstance();
		java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat(
				"yyyy-MM-dd");
		String date1 = dateFormat.format(new Date());
		ca.setTime(new Date());
		ca.roll(Calendar.DAY_OF_MONTH, -1);
		String date2 = dateFormat.format(ca.getTime());
		Number num = (Number) this.dao
				.uniqueResult("select count(*) from BBSDoc where status>=0 and (inputTime>='"
						+ date2 + "' and inputTime<'" + date1 + "')");
		return num;
	}

	public List getWeekMessages() {
		java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat(
				"yyyy-MM-dd");
		Calendar ca = Calendar.getInstance();
		ca.setTime(new Date());
		ca.roll(Calendar.DAY_OF_MONTH, -10);
		String week = dateFormat.format(ca.getTime());
		List msgs = docService
				.queryBBSDoc(" parentId is null or parentId = '' and status>=0 and inputTime>='"
						+ week + "'");
		return msgs;
	}

	public boolean topMessage(ActiveUser user, BBSDoc doc) {
		boolean ret = false;
		if (BBSRights.checkRights(doc, "tagTop", user)) {
			if (doc.getTopmessage() != null
					&& doc.getTopmessage().intValue() > 0)
				doc.setTopmessage(new Integer(0));
			else
				doc.setTopmessage(new Integer(1));
			ret = this.dao.update(doc);
		}
		return ret;
	}

	public boolean eliteMessage(ActiveUser user, BBSDoc doc) {
		boolean ret = false;
		if (BBSRights.checkRights(doc, "tagElite", user)) {
			if (doc.getElitemessage() != null
					&& doc.getElitemessage().intValue() > 0)
				doc.setElitemessage(new Integer(0));
			else
				doc.setElitemessage(new Integer(1));
			ret = this.dao.update(doc);
		}
		return ret;
	}

	public boolean lockMessage(ActiveUser user, BBSDoc obj) {
		boolean ret = false;
		if (BBSRights.checkRights(obj, "lockMessage", user)) {
			if (obj.getStatus() != null && (obj.getStatus().intValue() > 0))
				obj.setStatus(new Integer(0));// 解锁
			else
				obj.setStatus(new Integer(1));// 状态为1表示锁定
			com.knife.bbs.domain.BBSDoc doc=new com.knife.bbs.domain.BBSDoc();
			doc.setDoc(obj);
			ret = this.dao.update(doc);
		}
		return ret;
	}

	public boolean publishMessage(ActiveUser user, BBSDoc doc) {
		BBSDir dir = dirService.getBBSDirBySN(doc.getDirsn());
		boolean ret = false;
		if (dir != null) {
			if ((doc.getParentid() != null && (!doc.getParentid().equals("")))
					|| BBSRights.checkRights(dir, "publish", user))// 判断在栏目中的添加权限
			{
				//com.knife.bbs.domain.BBSDoc doc=new com.knife.bbs.domain.BBSDoc();
				//adoc.setCid(doc.getCid());
				//doc.setDoc(doc);
				IFilter filter = new ContentFilter();
				doc.setContent((String) filter.doFilter(doc.getContent()));// 执行过滤
				doc.setTitle((String) filter.doFilter(doc.getTitle()));// 执行过滤
				doc.setInputtime(new Date());
				doc.setInputuser(user.getUsername());
				doc.setIp(user.getIp());
				doc.setReadtimes(new Integer(0));
				doc.setReplynum(new Integer(0));
				doc.setScore(new Integer(0));
				doc.setBad(new Integer(0));
				doc.setGood(new Integer(0));
				doc.setStatus(new Integer(0));
				doc.setTopmessage(new Integer(0));
				doc.setElitemessage(new Integer(0));
				doc.setModifytime(doc.getInputtime());
				doc.setLastupdatetime(doc.getInputtime());
				doc.setDirpath(dir.getDirpath());
				if (doc.getVrtype() == null || doc.getVrtype().equals("")) {
					doc.setVrtype(dir.getVrtype());
					doc.setVrvalue(dir.getVrvalue());
				}
				com.knife.bbs.domain.BBSDoc adoc=new com.knife.bbs.domain.BBSDoc();
				adoc.setDoc(doc);
				ret = docService.add(adoc);
				if(!true){
					publishHtmlFile(doc);
				}
			}
			dir.setReplynum(dirService.replyNum(dir.getSn()));
			dir.setMessagenum(dirService.messageNum(dir.getSn()));
			dirService.update(dir);
		}
		if (ret) {
			BBSScore.addScore(user.getUsername(),
					doc.isReply() ? Score.get("rm") : Score.get("pm"),
					user.getUsername() + ":" + doc.getTitle() + ":发帖加分!");
		}
		return ret;
	}

	public boolean delMessage(ActiveUser user, BBSDoc obj) {
		boolean ret = false;
		if (BBSRights.checkRights(obj, "del", user)) {
			com.knife.bbs.domain.BBSDoc adoc=new com.knife.bbs.domain.BBSDoc();
			adoc.setDoc(obj);
			ret = this.dao.del(adoc);
		}
		if(!true){
			publishHtmlFile(obj);
		}
		return ret;
	}

	public boolean updateMessage(ActiveUser user, BBSDoc obj) {
		boolean ret = false;
		if (BBSRights.checkRights(obj, "update", user)) {
			IFilter filter = new ContentFilter();
			obj.setContent((String) filter.doFilter(obj.getContent()));// 执行过滤
			obj.setTitle((String) filter.doFilter(obj.getTitle()));// 执行过滤
			obj.setModifytime(new Date());
			obj.setLastupdatetime(new Date());
			obj.setLastupdateuser(user.getUsername());
			com.knife.bbs.domain.BBSDoc adoc=new com.knife.bbs.domain.BBSDoc();
			adoc.setDoc(obj);
			ret = this.dao.update(adoc);
		}
		// 重新发布
		if(!true){
			publishHtmlFile(obj);
		}
		return ret;
	}

	public void publishHtmlFile(BBSDoc obj) {
		if (obj.getParentid() != null && (!"".equals(obj.getParentid()))) {
			BBSDoc doc = docService.getBBSDoc(obj.getParentid());
			if (doc != null && doc.canPublish())
				saveToHTML(doc);
		} else if (obj.canPublish())
			saveToHTML(obj);
		else
			removeHtmlFile(obj);
	}

	public BBSDoc readMessage(ActiveUser user, String cid) {
		BBSDoc doc = new BBSDoc((com.knife.bbs.domain.BBSDoc) this.dao.get(com.knife.bbs.domain.BBSDoc.class, cid));
		if (!BBSRights.checkRights(doc, "read", user))
			doc = null;
		return doc;
	}

	public boolean replyMessage(ActiveUser user, BBSDoc doc) {
		boolean ret = false;
		com.knife.bbs.domain.BBSDoc parent = (com.knife.bbs.domain.BBSDoc) this.dao.get(com.knife.bbs.domain.BBSDoc.class, doc.getParentid());
		if (parent == null)
			return false;
		parent.setModifytime(new Date());
		if (user.getUsername().equals("guest")) {
			parent.setLastupdateuser("匿名");
			user.setUsername(user.getIp());
		} else
			parent.setLastupdateuser(user.getUsername());
		parent.setLastupdatetime(parent.getModifytime());
		parent.setReplynum(new Integer(parent.getReplynum() == null ? 1
				: parent.getReplynum().intValue() + 1));
		docService.update(parent);
		ret = publishMessage(user, doc);
		return ret;
	}

	public List listDir() {
		return dirService.queryBBSDir("status>=0 order by sequence");
	}

	public IPageList queryMessage(String scope, int pageSize, int pageNo) {
		return queryMessage(scope, null, pageSize, pageNo);
	}

	public IPageList queryMessage(String scope, Collection paras, int pageSize,
			int pageNo) {
		String sqlWhere = scope
				+ " and status>=0 and  (parentId is null or (parentId='')) order by topMessage desc,modifyTime desc";
		DbPageList pList = new DbPageList(com.knife.bbs.domain.BBSDoc.class, sqlWhere, paras);
		pList.doList(pageNo, pageSize);
		return pList;
	}

	public IPageList queryBBSDoc(String scope, Collection paras, int pageSize,
			int pageNo) {
		String sqlWhere = scope
				+ " and status >=0 order by topMessage desc,modifyTime desc";
		DbPageList pList = new DbPageList(com.knife.bbs.domain.BBSDoc.class, sqlWhere, paras);
		pList.doList(pageNo, pageSize);
		return pList;
	}

	public IPageList queryReply(BBSDoc doc, int pageSize, int pageNo) {
		String sqlWhere = "parentId='" + doc.getCid()
				+ "' and status>=0 order by inputTime ";
		DbPageList pList = new DbPageList(com.knife.bbs.domain.BBSDoc.class, sqlWhere, null);
		pList.doList(pageNo, pageSize);
		return pList;
	}

	public boolean saveToHTML(BBSDoc obj) {
		boolean ret = false;
		try {
			System.out.println("保存静态文件！");
			ret = HTMLGenerater.saveToHTML(obj);
			// Thread.sleep()
		} catch (Exception e) {
			System.out.println("保存静态文件错误！" + e);
			e.printStackTrace();
		}
		return ret;
	}

	public String replaceEmotTag(String s) {
		String makeContent = new String();
		String[] r = new String[50];
		for (int i = 1; i < 50; i++)
			r[i] = "\\[em" + (i < 10 ? "0" + i : i + "") + "\\]";// eval("/em"+(i<10?"0"+i:i+"")+"/;");
		StringTokenizer strToken = new StringTokenizer(s, "\n");
		while (strToken.hasMoreTokens()) {
			makeContent = makeContent + "<br>" + strToken.nextToken();
		}
		for (int i = 1; i < 50; i++) {
			makeContent = makeContent.replaceAll(r[i],
					"<img src=/images/emot/em" + (i < 10 ? "0" + i : i + "")
							+ ".gif>");// s.replace(r[i],"<img
			// src=img/emot/em"+(i<10?"0"+i:i+"")+".gif>");
		}
		r = null;
		return makeContent;
	}

	public boolean removeHtmlFile(BBSDoc doc) {
		String fileName = doc.staticHtmlUrl();
		File file = new File(Globals.APP_BASE_DIR + "/" + fileName);
		return file.exists() && file.delete();
	}

	public List<BBSDoc> changeListType(List<Object> objs){
		List<BBSDoc> results = new ArrayList<BBSDoc>();
		if(objs!=null){
			if(objs.size()>0){
				for (Object newobj : objs) {
					com.knife.bbs.domain.BBSDoc robj = (com.knife.bbs.domain.BBSDoc) newobj;
					BBSDoc tobj = new BBSDoc(robj);
					results.add(tobj);
				}
			}
		}
		return results;
	}
}
